// CivEditor.xaml.cs
//
// Copyright (c) 2007 Mike Strobel
//
// This source code is subject to the terms of the Microsoft Reciprocal License (Ms-RL).
// For details, see <http://www.opensource.org/licenses/ms-rl.html>.
//
// All other rights reserved.

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;

using DevComponents.WpfRibbon;

using Supremacy.Buildings;
using Supremacy.Economy;
using Supremacy.Entities;
using Supremacy.Orbitals;
using Supremacy.Tech;
using Supremacy.Universe;

namespace Supremacy.Editor
{
    /// <summary>
    /// Interaction logic for CivEditor.xaml
    /// </summary>
    public partial class CivEditor : EditorBase
    {
        #region Fields
        private readonly Dictionary<Type, TreeViewItem> _treeItemMap;

        private TechTree _techTree = null;
        private string _techTreeKey = null;
        private readonly ICollectionView _racesView;
        #endregion

        #region Constructors
        public CivEditor()
        {
            InitializeComponent();

            foreach (Quadrant quadrant in Enum.GetValues(typeof(Quadrant)))
                QuadrantList.Items.Add(quadrant);

            foreach (CivilizationType civType in Enum.GetValues(typeof(CivilizationType)))
                CivilizationTypeList.Items.Add(civType);

            foreach (TechCurve techCurve in Enum.GetValues(typeof(TechCurve)))
                TechCurveList.Items.Add(techCurve);

            _racesView = new ListCollectionView(EditorContext.Races);
            _racesView.SortDescriptions.Add(new SortDescription("PluralName", ListSortDirection.Ascending));
            RaceList.ItemsSource = _racesView;
            TechTree.SelectedItemChanged += TechTree_SelectedItemChanged;
            DeleteTechItemButton.IsEnabled = (TechTree.SelectedItem is TechObjectDesign);
            DataContextChanged += CivEditor_DataContextChanged;
            IdentityText.SourceUpdated += IdentityText_SourceUpdated;

            TechTree.KeyDown += TechTree_KeyDown;

            _treeItemMap = new Dictionary<Type, TreeViewItem>();
        }
        #endregion

        #region Methods
        private void AddTechItemButton_Click(object sender, RoutedEventArgs e)
        {
            this.AddTechItem();
        }

        private void AddTechItem()
        {
            if (_techTree == null)
                return;

            Dictionary<int, TechObjectDesign> omissions = new Dictionary<int, TechObjectDesign>();

            foreach (TechObjectDesign design in _techTree)
                omissions[design.DesignID] = design;

            foreach (TechObjectDesign design in EditorContext.TechDatabase)
            {
                if (design.IsUniversallyAvailable && !omissions.ContainsKey(design.DesignID))
                {
                    omissions[design.DesignID] = design;
                }
            }

            IList<TechObjectDesign> designs = TechObjectSelectorWindow.GetSelections(omissions.Values);

            if ((designs == null) || (designs.Count == 0))
                return;

            _techTree.AddMany(designs);

            _treeItemMap[typeof(BuildingDesign)].ItemsSource = null;
            _treeItemMap[typeof(BuildingDesign)].ItemsSource = _techTree.BuildingDesigns;
            _treeItemMap[typeof(ProductionFacilityDesign)].ItemsSource = null;
            _treeItemMap[typeof(ProductionFacilityDesign)].ItemsSource = _techTree.ProductionFacilityDesigns;
            _treeItemMap[typeof(ShipDesign)].ItemsSource = null;
            _treeItemMap[typeof(ShipDesign)].ItemsSource = _techTree.ShipDesigns;
            _treeItemMap[typeof(StationDesign)].ItemsSource = null;
            _treeItemMap[typeof(StationDesign)].ItemsSource = _techTree.StationDesigns;

        }

        private void CivEditor_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            DataTemplate treeItemTemplate = FindResource("TechObjectNameTemplate") as DataTemplate;
            Civilization civ = e.NewValue as Civilization;

            TechTree.Items.Clear();
            _treeItemMap.Clear();

            if (civ == null)
                return;

            ColorText.IsEnabled = (civ.CivilizationType == CivilizationType.Empire);

            if (!EditorContext.CivTechTrees.ContainsKey(civ.Key))
                EditorContext.CivTechTrees[civ.Key] = new TechTree();

            _techTreeKey = civ.Key;
            _techTree = EditorContext.CivTechTrees[_techTreeKey];

            TreeViewItem buildingsItem = new TreeViewItem();
            buildingsItem.Header = "Buildings";
            buildingsItem.IsExpanded = true;
            buildingsItem.Tag = typeof(BuildingDesign);
            buildingsItem.Items.SortDescriptions.Add(new SortDescription("Key", ListSortDirection.Ascending));
            buildingsItem.ItemsSource = _techTree.BuildingDesigns;
            buildingsItem.ItemTemplate = treeItemTemplate;

            TreeViewItem facilitiesItem = new TreeViewItem();
            facilitiesItem.Header = "Production Facilities";
            facilitiesItem.IsExpanded = true;
            facilitiesItem.Tag = typeof(ProductionFacilityDesign);
            facilitiesItem.Items.SortDescriptions.Add(new SortDescription("Key", ListSortDirection.Ascending));
            facilitiesItem.ItemsSource = _techTree.ProductionFacilityDesigns;
            facilitiesItem.ItemTemplate = treeItemTemplate;

            TreeViewItem shipsItem = new TreeViewItem();
            shipsItem.Header = "Ships";
            shipsItem.IsExpanded = true;
            shipsItem.Tag = typeof(ShipDesign);
            shipsItem.Items.SortDescriptions.Add(new SortDescription("Key", ListSortDirection.Ascending));
            shipsItem.ItemsSource = _techTree.ShipDesigns;
            shipsItem.ItemTemplate = treeItemTemplate;

            TreeViewItem stationsItem = new TreeViewItem();
            stationsItem.Header = "Space Stations";
            stationsItem.IsExpanded = true;
            stationsItem.Tag = typeof(StationDesign);
            stationsItem.Items.SortDescriptions.Add(new SortDescription("Key", ListSortDirection.Ascending));
            stationsItem.ItemsSource = _techTree.StationDesigns;
            stationsItem.ItemTemplate = treeItemTemplate;

            _treeItemMap[typeof(BuildingDesign)] = buildingsItem;
            _treeItemMap[typeof(ProductionFacilityDesign)] = facilitiesItem;
            _treeItemMap[typeof(ShipDesign)] = shipsItem;
            _treeItemMap[typeof(StationDesign)] = stationsItem;

            _treeItemMap[typeof(BuildingDesign)].ItemsSource = _techTree.BuildingDesigns;
            _treeItemMap[typeof(ProductionFacilityDesign)].ItemsSource = _techTree.ProductionFacilityDesigns;
            _treeItemMap[typeof(ShipDesign)].ItemsSource = _techTree.ShipDesigns;
            _treeItemMap[typeof(StationDesign)].ItemsSource = _techTree.StationDesigns;

            foreach (TreeViewItem treeItem in _treeItemMap.Values)
                TechTree.Items.Add(treeItem);

            TechTree.ApplyTemplate();

            DefineHomeSystemCheckBox.Checked += this.DefineHomeSystemCheckBox_Changed;
            DefineHomeSystemCheckBox.Unchecked += this.DefineHomeSystemCheckBox_Changed;

            if (EditorContext.HomeSystems.ContainsKey(civ.Key))
            {
                StarSystemDescriptor homeSystem = EditorContext.HomeSystems[civ.Key];
                if (!homeSystem.IsInhabitantsDefined)
                    homeSystem.Inhabitants = civ.RaceID;
                HomeSystemEditor.DataContext = homeSystem;
                DefineHomeSystemCheckBox.IsChecked = true;
            }
            else
            {
                HomeSystemEditor.DataContext = null;
                DefineHomeSystemCheckBox.IsChecked = false;
            }
        }

        private void DefineHomeSystemCheckBox_Changed(object sender, RoutedEventArgs e)
        {
            Civilization civ = DataContext as Civilization;
            if (civ != null)
            {
                if (DefineHomeSystemCheckBox.IsChecked.HasValue && DefineHomeSystemCheckBox.IsChecked.Value)
                {
                    StarSystemDescriptor homeSystem = EditorContext.GetOrCreateHomeSystem(civ);
                    if (!homeSystem.IsInhabitantsDefined)
                        homeSystem.Inhabitants = civ.RaceID;
                    HomeSystemEditor.DataContext = homeSystem;
                }
                else
                {
                    EditorContext.ClearHomeSystem(civ);
                    HomeSystemEditor.DataContext = null;
                }
            }
        }

        private void DeleteTechItem()
        {
            if (_techTree == null)
                return;

            if (TechTree.SelectedItem is TreeViewItem)
            {
                TreeViewItem treeItem = (TreeViewItem)TechTree.SelectedItem;
                MessageBoxResult result = MessageBox.Show(
                    "Delete all " + treeItem.Header + "?",
                    EditorApp.Current.MainWindow.Title,
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Question);
                if ((result == MessageBoxResult.Yes) && (treeItem.ItemsSource != null))
                {
                    IEnumerable oldItemSource = treeItem.ItemsSource;
                    treeItem.ItemsSource = null;
                    if (treeItem.Tag == typeof(BuildingDesign))
                        _techTree.ClearBuildingDesigns();
                    else if (treeItem.Tag == typeof(ProductionFacilityDesign))
                        _techTree.ClearProductionFacilityDesigns();
                    else if (treeItem.Tag == typeof(ShipDesign))
                        _techTree.ClearShipDesigns();
                    else if (treeItem.Tag == typeof(StationDesign))
                        _techTree.ClearStationDesigns();
                    treeItem.ItemsSource = oldItemSource;
                }
            }
            else if (TechTree.SelectedItem is TechObjectDesign)
            {
                TechObjectDesign design = (TechObjectDesign)TechTree.SelectedItem;
                _techTree.Remove(design);
                if (design.GetType() == typeof(BuildingDesign))
                {
                    _treeItemMap[typeof(BuildingDesign)].ItemsSource = null;
                    _treeItemMap[typeof(BuildingDesign)].ItemsSource = _techTree.BuildingDesigns;
                }
                else if (design.GetType() == typeof(ProductionFacilityDesign))
                {
                    _treeItemMap[typeof(ProductionFacilityDesign)].ItemsSource = null;
                    _treeItemMap[typeof(ProductionFacilityDesign)].ItemsSource = _techTree.ProductionFacilityDesigns;
                }
                else if (design.GetType() == typeof(ShipDesign))
                {
                    _treeItemMap[typeof(ShipDesign)].ItemsSource = null;
                    _treeItemMap[typeof(ShipDesign)].ItemsSource = _techTree.ShipDesigns;
                }
                else if (design.GetType() == typeof(StationDesign))
                {
                    _treeItemMap[typeof(StationDesign)].ItemsSource = null;
                    _treeItemMap[typeof(StationDesign)].ItemsSource = _techTree.StationDesigns;
                }
            }
        }

        private void DeleteTechItemButton_Click(object sender, RoutedEventArgs e)
        {
            DeleteTechItem();
        }

        private void IdentityText_SourceUpdated(object sender, DataTransferEventArgs e)
        {
            EditorContext.CivTechTrees.Remove(_techTreeKey);
            _techTreeKey = IdentityText.Text;
            EditorContext.CivTechTrees[_techTreeKey] = _techTree;
        }

        private void TechTree_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                DeleteTechItem();
            }
        }

        private void TechTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            DeleteTechItemButton.IsEnabled = (TechTree.SelectedItem != null);
        }
        #endregion

        private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if ((e.Command == ApplicationCommands.New) || (e.Command == ApplicationCommands.Delete))
            {
                e.CanExecute = TechTree.IsKeyboardFocusWithin;
            }
        }

        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (e.Command == ApplicationCommands.New)
            {
                AddTechItem();
            }
            else if (e.Command == ApplicationCommands.Delete)
            {
                DeleteTechItem();
            }
        }
    }
}